package at.ac.tuwien.swa.sparrow.server.component

import at.ac.tuwien.swa.sparrow._
import at.ac.tuwien.swa.sparrow.common.AuthToken
import at.ac.tuwien.swa.sparrow.server.persistence.AccountRepository
import at.ac.tuwien.swa.sparrow.server.security.SecurityContext
import javax.inject.Inject
import org.springframework.stereotype.Component
import scala.collection.mutable

@Component
class UserManager @Inject()(accountRepository: AccountRepository) {

	val sessions = mutable.Set[String]()
	val tokens = new mutable.HashMap[String, mutable.Set[AuthToken]] with mutable.MultiMap[String, AuthToken]

	def login(username: String, authToken: AuthToken) = {
		logout(username)

		SecurityContext.setRole(accountRepository(authToken.id))
		sessions += username
		tokens.addBinding(username, authToken)
	}

	def logout(username: String) = {
		SecurityContext.setRole(null)
		sessions -= username

		lastToken(username) match {
			case None => tokens -= username
			case Some(t) =>
				if (t.timestamp < System.currentTimeMillis() - 2 * SESSION_DURATION.toMillis) tokens -= username
		}
	}

	private def lastToken(username: String): Option[AuthToken] = {
		val userTokens = tokens getOrElse(username, Set.empty[AuthToken])
		if (userTokens.isEmpty) None
		else Some(userTokens maxBy (_.timestamp))
	}

	def isOnline(username: String) = sessions.contains(username)

	def validTokens(username: String) = tokens getOrElse(username, Set.empty[AuthToken]) filterNot (_.isExpired)

}
